package upload

import (
	"context"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/util/guid"
	"github.com/tencentyun/cos-go-sdk-v5"
	"net/http"
	"net/url"
	"path/filepath"
	"server/internal/consts"
	"server/internal/model"
	"server/internal/service"
)

// 1.开通腾讯云cos对象服务
// 2.创建桶空间bucket
// 3.新增API的秘钥后在配置文件进行配置（建议新增子账号api秘钥） fileUpload.tenCent  https://cloud.tencent.com/document/product/598/37140

type TenCentUpload struct {
}

func (T *TenCentUpload) UploadFile(ctx context.Context, file *ghttp.UploadFile, fileSubject string) (out model.FileUploadOutput, err error) {
	client := T.newClient(ctx)
	if client == nil {
		err = gerror.New("腾讯云Cos服务客户端创建失败")
		return
	}
	// 生成一个文件路径作为文件对象的KEY
	filename := guid.S() + filepath.Ext(file.Filename)
	objectKey := GenerateUploadFilePath(ctx, filename, consts.FileUploadStorageTypeTenCentCos, fileSubject)
	// 判断文件是否存在
	exist, err := client.Object.IsExist(ctx, objectKey)
	if err != nil {
		return
	}
	if exist {
		err = gerror.New("文件名已存在，上传失败")
		return
	}
	// 上传文件
	if fileReader, err := file.Open(); err != nil {
		return out, err
	} else if _, err = client.Object.Put(ctx, objectKey, fileReader, nil); err != nil {
		return out, err
	}
	// 处理文件上传后的相关路径
	out.AbsolutePath = objectKey
	out.RelativePath = objectKey
	out.URL = FormatUploadFileURL(ctx, objectKey, consts.FileUploadStorageTypeTenCentCos)
	return
}

func (T *TenCentUpload) DeleteFile(ctx context.Context, key string) (err error) {
	client := T.newClient(ctx)
	if client == nil {
		err = gerror.New("腾讯云Cos服务客户端创建失败")
		return
	}
	// 判断文件是否存在
	exist, err := client.Object.IsExist(ctx, key)
	if err != nil {
		return
	}
	if !exist {
		err = gerror.New("文件不存在，删除失败")
		return
	}
	// 删除文件
	_, err = client.Object.Delete(ctx, key)
	if err != nil {
		return
	}
	return nil
}

func (T *TenCentUpload) newClient(ctx context.Context) (client *cos.Client) {
	config, err := service.File().GetFileUploadConfig(ctx)
	if err != nil {
		return
	}
	bucketURL, _ := url.Parse(config.TenCentCos.BucketUrl)
	su, _ := url.Parse(config.TenCentCos.Endpoint)
	b := &cos.BaseURL{BucketURL: bucketURL, ServiceURL: su}
	client = cos.NewClient(b, &http.Client{
		Transport: &cos.AuthorizationTransport{
			SecretID:  config.TenCentCos.AccessKeyId,
			SecretKey: config.TenCentCos.AccessKeySecret,
		},
	})
	return client
}
